package cn.afterturn.svn.analysis.svn;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNLogEntryPath;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

import cn.afterturn.svn.analysis.entity.historyinfo.HistoryInfoEntity;
import cn.afterturn.svn.analysis.entity.historypath.HistoryPathEntity;
import cn.afterturn.svn.analysis.entity.repositoryinfo.RepositoryInfoEntity;

/**
 * 获取这个项目的更新日志
 * @author JueYue
 * @date 2015年7月29日 下午5:07:42
 */

public class SvnHistory {

    private static final Log LOG = Logs.get();

    /**
     * 获取这个项目的最近更新日志
     * @param svnInfo
     * @return
     */
    public static List<HistoryInfoEntity> getHistory(RepositoryInfoEntity svnInfo) {
        List<HistoryInfoEntity> resultList = new ArrayList<HistoryInfoEntity>();
        setupLibrary();
        try {
            SVNRepository repository = SVNRepositoryFactory
                .create(SVNURL.parseURIEncoded(svnInfo.getUrl()));
            ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(
                svnInfo.getName(), svnInfo.getPassword().toCharArray());
            repository.setAuthenticationManager(authManager);
            long endRevision = repository.getLatestRevision();
            @SuppressWarnings("unchecked")
            Collection<SVNLogEntry> logEntries = (Collection<SVNLogEntry>) repository
                .log(new String[] { "" }, null, svnInfo.getLastRevision(), endRevision, true, true);
            for (Iterator<SVNLogEntry> entries = logEntries.iterator(); entries.hasNext();) {
                resultList.add(getHistroyInfo(entries.next(), svnInfo));

            }
        } catch (Exception e) {
            LOG.error(e);
        }
        return resultList;
    }

    /**
     * 获取这个日志的详细信息
     * @param log
     * @param svnInfo
     * @return
     */
    private static HistoryInfoEntity getHistroyInfo(SVNLogEntry log, RepositoryInfoEntity svnInfo) {
        HistoryInfoEntity entity = new HistoryInfoEntity();
        entity.setAuthor(log.getAuthor());
        entity.setRevision(log.getRevision());
        entity.setDate(log.getDate());
        entity.setLogMessage(log.getMessage());
        entity.setRepositoryId(svnInfo.getId());
        entity.setFileNum(log.getChangedPaths().size());
        if (log.getChangedPaths().size() > 0) {
            Set<String> changedPathsSet = log.getChangedPaths().keySet();
            List<HistoryPathEntity> paths = new ArrayList<HistoryPathEntity>();
            for (Iterator<String> changedPaths = changedPathsSet.iterator(); changedPaths
                .hasNext();) {
                SVNLogEntryPath entryPath = (SVNLogEntryPath) log.getChangedPaths()
                    .get(changedPaths.next());
                HistoryPathEntity path = new HistoryPathEntity();
                path.setPath(entryPath.getPath());
                path.setType(String.valueOf(entryPath.getType()));
                entity.setPaths(paths);
            }
        }
        return entity;
    }

    private static void setupLibrary() {
        /*
         * For using over http:// and https://
         */
        DAVRepositoryFactory.setup();
        /*
         * For using over svn:// and svn+xxx://
         */
        SVNRepositoryFactoryImpl.setup();

        /*
         * For using over file:///
         */
        FSRepositoryFactory.setup();
    }
}